package com.harboursoftware.xstorage.operations;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.ListMultimap;
import com.harboursoftware.xstorage.Constants;
import com.harboursoftware.xstorage.XStorageException;
import com.harboursoftware.xstorage.ac.AccessControlPolicy;
import com.harboursoftware.xstorage.ac.InvalidCannedAccessPolicyException;
import com.harboursoftware.xstorage.ac.Permission;
import com.harboursoftware.xstorage.fs.BucketAlreadyOwnedByOtherUserException;
import com.harboursoftware.xstorage.model.XBucket;
import com.harboursoftware.xstorage.model.XElement;
import com.harboursoftware.xstorage.model.XUser;
import com.harboursoftware.xstorage.results.EmptyContentResult;
import com.harboursoftware.xstorage.results.ErrorResult;
import com.harboursoftware.xstorage.results.Result;
import com.harboursoftware.xstorage.util.MultimapUtils;

/**
 * This class is the implements of <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/API/">PUT
 * Bucket(Amazon S3 REST API Version 2006-03-01))</a>.
 * 
 * @author Simon Leung
 * @since 0.1
 */
public class PutBucket extends Operation {
    private final static Logger log = LoggerFactory.getLogger(PutBucket.class);

    @Override
    public Result execute(XUser requester, XElement element, ListMultimap<String, String> headers,
        Map<String, String> parameters) throws XStorageException {
        log.debug("excute");
        if(requester == null || requester.getId() == null) { // anonymous,access denied
        	ErrorResult errorResult = ErrorResult.create(ErrorResult.Type.ACCESS_DENIED);
        	errorResult.setMessage("Anonymous access is forbidden for this operation");
        	return errorResult;
        }
        XBucket bucket = (XBucket) element;
        if (!bucket.hasValidDNSName()) {
        	ErrorResult errorResult = ErrorResult.create(ErrorResult.Type.INVALID_BUCKET_NAME);
        	errorResult.addOtherInfo("BucketName", bucket.getName());
			return errorResult;
        }
        try {
            //TODO:判断用户拥有的Bucket是否超过100个
            AccessControlPolicy cannedAcp = getCannedAcpSpecifiedOnHeader(requester, headers);
            bucket.setAcp(cannedAcp);
            bucket.setOwner(requester);
            fileSystem.createBucket(bucket);
            return new EmptyContentResult();
        } catch (InvalidCannedAccessPolicyException e) {
        	ErrorResult errorResult = ErrorResult.create(ErrorResult.Type.INVALID_ARGUMENT);
        	errorResult.addOtherInfo("ArgumentName", Constants.REST_METADATA_ACL);
        	errorResult.addOtherInfo("ArgumentValue", e.getInvaildCannedAccessPolicy());
			return errorResult;
		} catch (BucketAlreadyOwnedByOtherUserException e) {
			ErrorResult errorResult = ErrorResult.create(ErrorResult.Type.BUCKET_ALREADY_EXISTS);
			errorResult.addOtherInfo("BucketName", bucket.getName());
			return errorResult;
        }
    }

    /**
     * 获得在headers制定的acp，但在不存在指定的canned acp的情况下返回默认的ACP
     * 
     * @param headers
     * @return
     * @throws InvalidCannedAccessPolicyException 
     */
    private AccessControlPolicy getCannedAcpSpecifiedOnHeader(XUser owner, ListMultimap<String, String> headers) throws InvalidCannedAccessPolicyException {
        String cannedAccessPolicyLabel = MultimapUtils.getFirstValue(headers, Constants.REST_METADATA_ACL);
        
        AccessControlPolicy cannedAccessPolicy =
            AccessControlPolicy.createCannedAccessPolicy(cannedAccessPolicyLabel, owner, owner);

        return cannedAccessPolicy;
    }

    @Override
    public Permission getRequiredPermission() {
        return null;
    }
}
